/**
 * Copyright (C) 2015-2018 IQIYI
 * All rights reserved.
 *
 * Author     : 王海斌
 * E-mail     : wanghaibin@qiyi.com
 * Version    :
 * Date       : Wed 21 Nov 2018 04:03:56 PM CST
 * Destription:
 *
 */
#include <iostream>
#include <string>
#include <stdio.h>
#include <set>
#include <vector>

using namespace std;

typedef struct IpInfo_t
{
    std::string ip_;        //ip地址
    std::string port_;      //端口号
    unsigned int priority_; //优先级
    int type_;           //ip类型
    bool operator<(const IpInfo_t& right) const
    {//set 集合排序使用
        if(type_ < right.type_)
            return true;
        else if(type_ > right.type_)
            return false;
        else if(priority_ < right.priority_)
            return true;
        else if(priority_ > right.priority_)
            return false;
        else
            return ip_ < right.ip_;
    }
} IpInfo_t;


//测试set对象自定义比较函数
void test_set_compare() {
    std::set<IpInfo_t> availableIps_;
    for(int i=0; i<10; ++i) {
        IpInfo_t tmp;
        char data[32]={0};
        snprintf(data,32,"ip%d", i);
        tmp.ip_=data;
        tmp.port_ = "80";
        tmp.priority_ = i;
        tmp.type_ = i;
        availableIps_.insert(tmp);
    }
    IpInfo_t tmp;
    tmp.ip_="ip8";
    tmp.port_ = "80";
    tmp.priority_ = 8;
    tmp.type_ = 8;

    std::set<IpInfo_t>::iterator it = availableIps_.find(tmp);
    if(it == availableIps_.end()) {
        printf("not find 8\n");
    } else {
        availableIps_.erase(it);
        printf("find 8\n");
    }

    printf("availableIps_.size=%d\n", availableIps_.size());
}

// 测试一边遍历一边删除符合条件的元素
void test_loop_erase()
{
    std::set<int*> t1;
    for(int i=0; i<10; ++i) {
        int * tmp = new int;
        *tmp = i;
        t1.insert(tmp);
    }
    // 由于erase指定元素无返回值, 所以要使用2个变量标记
    std::set<int*>::iterator it=t1.begin(), next;
    for (next=it; it != t1.end();it=next) {
        ++next;
        int * tmmp = (*it);
        if((*tmmp)==4) {
            delete tmmp;
            printf("delete=%d\n", *(*it));
            t1.erase(it);
            printf("size=%zd\n", t1.size());
        } else {
            printf("x=%d\n", *(*it));
        }
    }
}

//测试2个同类型set的合并
void test_set_merge() {
    std::set<int> seta, setb;
    for(int i=0; i<10; i++) {
        seta.insert(i);
        setb.insert(i+8);
    }

    setb.insert(seta.begin(), seta.end());

    std::vector<int> vec;
    for(int i=100; i<110; ++i) {
        vec.push_back(i);
    }
    setb.insert(vec.begin(), vec.end());

    std::set<int>::const_iterator cit = setb.begin();
    for(; cit!=setb.end(); ++cit) {
        printf("i=%d\n", *cit);
    }
}

// 测试拷贝set内容vector中的高效做法
void test_copy_set_to_vector() {
    std::set<int> s;
    for(int i=0; i<20; i++) {
        s.insert(i);
    }
    std::vector<int> v;
    std::copy(s.lower_bound(5), s.end(), std::back_inserter(v));
	std::string tmp;
    for(auto it=v.begin(); it!=v.end(); ++it) {
		tmp.append(std::to_string(*it)).append(",");
    }
	printf("lower_bound(5)~~end=%s\n", tmp.c_str());
	v.clear();
	tmp.clear();
    std::copy(s.begin(), s.lower_bound(5),  std::back_inserter(v));
    for(auto it=v.begin(); it!=v.end(); ++it) {
		tmp.append(std::to_string(*it)).append(",");
    }
	printf("begin() ~~~ lower_bound(5)=%s\n", tmp.c_str());
}

int main(int argc, char *argv[])
{
    test_copy_set_to_vector();
    return 0;
    test_set_merge();
    return 0;
    test_loop_erase();
    return 0;
    test_set_compare();
    return 0;
}

